# -*- coding: utf-8 -*-
import csv
import pickle
from datetime import datetime
from uuid import uuid1

import ezdxf
import json

from ezdxf.math import Vec3
from ezdxf.math.ellipse import minor_axis
from app.configs import tmp_path, kj236_pool
from app.models import db_session
from app.models.dao import _entity
from app.models.dao import db2vectors
from app.models.model import TrackModel, MineModel, PositionModel, LayerModel
from app.tools.utils import csv_float, csv_int, distance, foot_point, point_in_box, THRESHOLD, arc, ellipse, box


# def huluwan():
#     doc = ezdxf.new()
#     doc.styles.add("Arial", font="Arial.ttf")
#     msp = doc.modelspace()
#
#     with open(data_path + "hlw" + "\\" + "hlw.json", 'rb') as f:
#         content = f.read()
#     vehicle_json = json.loads(content)
#     for item in vehicle_json['features']:
#         pts = item['geometry']['coordinates']
#         msp.add_lwpolyline(points=pts, close=False, dxfattribs={})
#
#     with open(data_path + "hlw" + "\\" + "hlw.csv", encoding="utf-8") as f:
#         for station in csv.reader(f, skipinitialspace=True):
#             cont = {'text': station[1], 'insert': [float(station[3]), float(station[4])]}
#             msp.add_text(station[1], dxfattribs=cont)
#
#     doc.saveas(data_path + "hlw" + "\\" + "a.dxf")


def baode_water(file):
    doc = ezdxf.readfile(filename=file, encoding='utf-8')
    msp = doc.modelspace()
    areas = {"type": "FeatureCollection", "features": []}
    features = areas["features"]

    for entity in msp:
        if (entity.dxf.layer == "物探富水区" or entity.dxf.layer == "0") and entity.dxftype() == "HATCH":
            coordinates = []
            for path in entity.paths:
                name = type(path).__name__
                if name == 'PolylinePath':
                    coordinates = [[i[0], i[1]] for i in path.vertices]
                    coordinates.append(coordinates[0])
                else:
                    for e in path.edges:
                        edge_type = e.EDGE_TYPE
                        if edge_type == 'LineEdge':
                            coordinates.append([e.start.x, e.start.y])
                            coordinates.append([e.end.x, e.end.y])
                        elif edge_type == 'ArcEdge':
                            points = arc(e.center[0], e.center[1], e.radius, e.start_angle, e.end_angle)
                            for p in points:
                                coordinates.append(p)
                            if len(path.edges) == 1:
                                coordinates.append(coordinates[0])
                        elif edge_type == 'SplineEdge':
                            for p in e.control_points:
                                coordinates.append(p)
                        elif edge_type == 'EllipseEdge':
                            minor_axiss = minor_axis(e.major_axis, Vec3(0, 0, 1), e.ratio)
                            x, y = e.center[0], e.center[1]
                            ux, uy = e.major_axis[0], e.major_axis[1]
                            vx, vy = minor_axiss[0], minor_axiss[1]
                            points = ellipse(x, y, ux, uy, vx, vy, e.start_param, e.end_param)
                            for p in points:
                                coordinates.append(p)
                            if len(path.edges) == 1:
                                coordinates.append(coordinates[0])

            result = {
                "type": "Feature",
                "geometry": {
                    "type": "Polygon",
                    "coordinates": coordinates
                },
                "properties": {
                    "AREA": "Water"
                }
            }
            features.append(result)

    lines_file = tmp_path + "areas.json"
    with open(lines_file, "w") as fw:
        fw.write(json.dumps(areas))


def baode_water_v2(file, meta_id=""):
    doc = ezdxf.readfile(filename=file, encoding='utf-8')
    session, msp = db_session(), doc.modelspace()
    l, r, t, b, new_layers = None, None, None, None, []
    old_layers = [item["layer"] for item in db2vectors(LayerModel, meta_id)]

    # 添加形状类型
    for entity in msp:
        if entity.dxftype() == "LWPOLYLINE":
            continue
        l, r, t, b = _entity(session, entity, l, r, t, b, meta_id)
        if entity.dxf.layer not in new_layers:
            new_layers.append(entity.dxf.layer)

    #  获取styles信息
    for name, entity in doc.layers.entries.items():
        if name in old_layers:
            continue
        if name in new_layers:
            layer = LayerModel(entity, meta_id)
            session.add(layer)

    session.commit()
    session.close()


def baode_none_water(file, meta_id=""):
    doc = ezdxf.readfile(filename=file, encoding='utf-8')
    session, msp = db_session(), doc.modelspace()
    l, r, t, b, new_layers = None, None, None, None, []
    old_layers = [item["layer"] for item in db2vectors(LayerModel, meta_id)]

    # 添加形状类型
    for entity in msp:
        layer = entity.dxf.layer
        if layer == "(测)井巷积水" or layer == "（机）排水管路" or layer == "积水区" or layer == "泰山隆安煤业采掘图":
            l, r, t, b = _entity(session, entity, l, r, t, b, meta_id)
            if layer not in new_layers:
                new_layers.append(entity.dxf.layer)
    print(new_layers)

    #  获取styles信息
    for name, entity in doc.layers.entries.items():
        if name in old_layers:
            continue
        if name in new_layers:
            layer = LayerModel(entity, meta_id)
            session.add(layer)

    session.commit()
    session.close()


def person(meta_id):
    session = db_session()
    fetchall = kj236_pool.select("SELECT * from m_geojson WHERE id='default.tdwp.paths'")
    # cursor.execute("SELECT * from m_geojson WHERE id='default_tianshan'")
    person_track, person_json = [], fetchall[0][2]
    for feature in person_json['features']:
        track = TrackModel(feature["geometry"]["coordinates"], meta_id)
        track.dxftype = "person"
        session.add(track)
    session.commit()

    tracks = db2vectors(TrackModel, meta_id)
    fetchall = kj236_pool.select("SELECT * from m_position")
    for item in fetchall:
        if item[3] is None and item[4] is None:
            continue

        pt = [item[3], item[4]]
        for track in tracks:
            if track['type'] != 'person':
                continue

            l, r = track['left'], track['right']
            b, t = track['bottom'], track['top']
            if point_in_box(pt, l, r, t, b) is False:
                continue

            points = track['points']
            for i in range(0, len(points) - 1):
                ls, le, fp = points[i], points[i + 1], [0, 0]
                if foot_point(pt, ls, le, fp):
                    if distance(pt[0], pt[1], fp[0], fp[1]) < THRESHOLD:
                        points.insert(i + 1, pt)
                        position = PositionModel(pt, meta_id)
                        position.insert_id = str(track['id'])
                        position.dxftype = 'person'
                        position.node_id = item[1]
                        session.add(position)
                        ts = session.query(TrackModel).filter(TrackModel.id == track['id']).all()
                        for t in ts:
                            t.points = pickle.dumps(points)
                        session.commit()
                        break
    session.close()


# def vehicle(meta_id):
#     kj236 = project.kj236()
#     cursor, session = kj236.cursor(), db_session()
#     # cursor.execute("SELECT *  from m_geojson WHERE id='vehicle.wpmk.paths'")
#     cursor.execute("SELECT *  from m_geojson WHERE id='default.vehicle.paths'")
#     vehicle_tracks, vehicle_json = [], cursor.fetchall()[0][2]
#     for feature in vehicle_json['features']:
#         track = TrackModel(feature["geometry"]["coordinates"], meta_id)
#         track.dxftype = "vehicle"
#         session.add(track)
#     session.commit()
#
#     cursor.execute("SELECT * from m_position_vehicle")
#     fetchall, tracks = cursor.fetchall(), db2vectors(TrackModel, meta_id)
#     for item in fetchall:
#         if item[3] is None and item[4] is None:
#             continue
#
#         pt = [item[3], item[4]]
#         for track in tracks:
#             if track['type'] != 'vehicle':
#                 continue
#
#             l, r = track['left'], track['right']
#             b, t = track['bottom'], track['top']
#             if point_in_box(pt, l, r, t, b) is False:
#                 continue
#
#             points = track['points']
#             for i in range(0, len(points) - 1):
#                 ls, le, fp = points[i], points[i + 1], [0, 0]
#                 if foot_point(pt, ls, le, fp):
#                     if distance(pt[0], pt[1], fp[0], fp[1]) < THRESHOLD:
#                         points.insert(i + 1, pt)
#                         position = PositionModel(pt, meta_id)
#                         position.insert_id = str(track['id'])
#                         position.dxftype = 'vehicle'
#                         position.node_id = item[1]
#                         session.add(position)
#                         ts = session.query(TrackModel).filter(TrackModel.id == track['id']).all()
#                         for t in ts:
#                             t.points = pickle.dumps(points)
#                         session.commit()
#                         break
#     session.close()


# def driving_lane():
#     kj236 = project.kj236()
#     cursor, session = kj236.cursor(), db_session()
#
#     # 分站数组
#     cursor.execute("SELECT *  from m_reader")
#     readers, fetchall = {}, cursor.fetchall()
#     for item in fetchall:
#         readers[item[2]] = item[0]
#
#     # 轨迹线数组
#     # cursor.execute("SELECT *  from m_geojson WHERE id='vehicle.wpmk.paths'")
#     cursor.execute("SELECT *  from m_geojson WHERE id='default.vehicle.paths'")
#     tracks, vehicle_json = {}, cursor.fetchall()[0][2]
#     for feature in vehicle_json['features']:
#         l, r, t, b = None, None, None, None
#         coordinates = feature["geometry"]["coordinates"]
#         for p in coordinates:
#             l, r, t, b = box(l, r, t, b, p)
#         trackid = str(str(uuid1()))
#         track = {
#             "id": trackid,
#             "left": math.floor(l),
#             "right": math.ceil(r),
#             "top": math.ceil(t),
#             "bottom": math.floor(b),
#             "points": coordinates
#         }
#         tracks[trackid] = track
#
#     # 分站数组
#     cursor.execute("SELECT * from m_position_vehicle")
#     positions, fetchall = [], cursor.fetchall()
#     for item in fetchall:
#         if item[3] is None and item[4] is None:
#             continue
#
#         position = {
#             "id": str(uuid1()),
#             "x": item[3],
#             "y": item[4],
#             "readerid": readers[item[1]],
#             "track_id": None
#         }
#
#         flag, pt = False, [item[3], item[4]]
#         for track in tracks.values():
#             l, r = track['left'], track['right']
#             b, t = track['bottom'], track['top']
#             if point_in_box(pt, l, r, t, b) is False:
#                 continue
#
#             flag, points = False, track['points']
#             for i in range(0, len(points) - 1):
#                 ls, le, fp = points[i], points[i + 1], [0, 0]
#                 if foot_point(pt, ls, le, fp):
#                     if distance(pt[0], pt[1], fp[0], fp[1]) < THRESHOLD:
#                         points.insert(i + 1, pt)
#                         position["track_id"] = str(track['id'])
#                         flag = True
#                         break
#             if flag:
#                 break
#
#         # 如果没有查找到估计线
#         if position["track_id"] is None:
#             continue
#
#         positions.append(position)
#
#     # 清理一下轨迹线的重复点
#     for track in tracks.values():
#         points = [track['points'][0]]
#         for i in range(1, len(track['points'])):
#             last = len(points) - 1
#             x1, y1 = points[last][0], points[last][1]
#             x2, y2 = track['points'][i][0], track['points'][i][1]
#             if distance(x1, y1, x2, y2) < THRESHOLD:
#                 continue
#             points.append([x2, y2])
#         track['points'] = points
#
#     # 一个一个分站进行处理,找到其下一个分站
#     lanes = []
#     for p in positions:
#         track, index = tracks[p["track_id"]], 0
#
#         # 找到当前分站在轨迹线的位置
#         for i in range(len(track["points"])):
#             pt = track["points"][i]
#             if distance(pt[0], pt[1], p['x'], p['y']) < THRESHOLD:
#                 index = i
#                 break
#
#         # 向后查找,是否有满足的分站
#         lane = {"start": p["readerid"], "end": None, "distance": 0}
#         for i in range(index + 1, len(track["points"])):
#             flag, pt, pd = False, track["points"][i], track["points"][i - 1]
#             lane["distance"] += distance(pt[0], pt[1], pd[0], pd[1])
#             for p2 in positions:
#                 # 如果是分站自身,直接不处理
#                 if p["readerid"] == p2["readerid"]:
#                     continue
#                 # 如果查找到它的下一个分站,则放入结果集里
#                 if distance(pt[0], pt[1], p2['x'], p2['y']) < THRESHOLD:
#                     lane["end"] = p2["readerid"]
#                     flag = True
#                     break
#             if flag:
#                 break
#
#         # 如果没有找到尾部点
#         if lane["end"] is None:
#             # 则看一下当前轨迹线是否有接续轨迹线
#             pt = track["points"][len(track["points"]) - 1]
#             for track2 in tracks.values():
#                 # 如果是自己的情况
#                 if track["id"] == track2["id"]:
#                     continue
#
#                 flag, pd = False, track2["points"][0]
#                 if distance(pt[0], pt[1], pd[0], pd[1]) < THRESHOLD:
#                     # 证明在这里存在接续,遍历接续
#                     for i in range(1, len(track2["points"])):
#                         pt, pd = track2["points"][i], track2["points"][i-1]
#                         lane["distance"] += distance(pt[0], pt[1], pd[0], pd[1])
#                         for p2 in positions:
#                             # 如果是分站自身,直接不处理
#                             if p["readerid"] == p2["readerid"]:
#                                 continue
#
#                             if distance(pt[0], pt[1], p2['x'], p2['y']) < THRESHOLD:
#                                 flag = True
#                                 lane["end"] = p2["readerid"]
#                                 break
#                         if flag:
#                             break
#         lanes.append(lane)
#
#     # 最后插入数据
#     query = """
#         INSERT INTO m_driving_lane(id, enable, type, point1_pos_rdnum, point2_pos_rdnum, remark, save_time)
#         VALUES (%s, %s, %s, %s, %s, %s, %s)
#     """
#     for lane in lanes:
#         end = lane['end'] if lane['end'] is not None else ""
#         d = lane['distance'] if lane['end'] is not None else 0
#         values = (str(uuid1()), True, 2, lane['start'], end, d, datetime.now())
#         cursor.execute(query, values)
#     kj236.commit()


def csv2mine(file):
    session = db_session()

    with open(file, encoding="utf-8") as f:
        for c in csv.reader(f, skipinitialspace=True):
            mine = MineModel()
            # mine.id = int(c[0])
            mine.mine_code = c[1]
            mine.mine_name = c[2]
            mine.mine_pinyin = c[3]
            mine.mine_pinyin_first = c[4]
            mine.mine_yield = csv_float(c[5])
            mine.mine_yield_check = csv_float(c[6])
            mine.check_date = None
            mine.provice = c[8]
            mine.city = c[9]
            mine.county = c[10]
            mine.township = c[11]
            mine.address = c[12]
            mine.provincial_office = c[13]
            mine.suboffice_name = c[14]
            mine.group_name = c[15]
            mine.coalseam_num = csv_float(c[16])
            mine.mine_area = csv_float(c[17])
            mine.build_time = None
            mine.longitude = csv_float(c[19])
            mine.latitude = csv_float(c[20])
            mine.description = c[21]
            mine.mine_status = csv_int(c[22])
            mine.gas_level = csv_int(c[23])
            mine.water_condition = csv_int(c[24])
            mine.rock_burst_tendency = csv_int(c[25])
            mine.roof_hazard_type = csv_int(c[26])
            mine.coal_fire_tendency = csv_int(c[27])
            mine.dust_explosion_danger = csv_int(c[28])
            session.add(mine)

    session.commit()
    session.close()


if __name__ == "__main__":
    # driving_lane()
    # baode_water(tmp_path + "a.dxf")
    # baode_water_v2(tmp_path + "a.dxf", "98972d07-d911-11ed-823d-401c83e68899")
    # vehicle("vehicle")
    # person("person")
    # huluwan()
    # (测)井巷积水 | （机）排水管路 | 积水区 | 泰山隆安煤业采掘图
    # baode_none_water(tmp_path + "b.dxf", "98972d07-d911-11ed-823d-401c83e68899")
    pass
